<?php
namespace plugins\appmarket\controller; //Demo插件英文名，改成你的插件英文就行了
use cmf\controller\PluginAdminBaseController;//引入此类
use think\Db;
use think\Validate;
use app\common\lib\AccessAuthorization;
use plugins\appmarket\controller\ModuleCategoryController;
use plugins\appmarket\lib\Upload;
use plugins\appmarket\controller\ConfigController;

/**
 * 发布管理控制器
 */
class PublishController extends PluginAdminBaseController
{
    /**
     * 文件存储根目录
     * @var string
     */
    private $rootPath = "upload/module";

   	protected function _initialize()
    {
        parent::_initialize();
        $adminId = cmf_get_current_admin_id();
        //获取后台管理员id，可判断是否登录
        if (!empty($adminId)) {
            $this->assign("admin_id", $adminId);
        }
    }

    static public $statusColor = [ '#FF9800' , '#007AAE' , 'red' , 'red' , 'green' ];
    static public $statusStr = ['未提交','审核中','审核失败','未完成','已通过']; 


    /**
     * 发布管理首页
     * @adminMenu(
     *     'name'   => '发布管理',
     *     'parent' => 'AdminIndex/index',
     *     'display'=> true,
     *     'hasView'=> true,
     *     'order'  => 1000,
     *     'icon'   => '',
     *     'remark' => '发布管理',
     *     'param'  => ''
     * )
     */
    public function index()
    {
        $data = $this->request->param();
        $search = [
            'search'    =>  isset( $data [ 'search' ] ) ? $data [ 'search' ] : NULL,
            'module'    =>  isset( $data [ 'module' ] ) ? $data [ 'module' ] : 100,
            'author'    =>  isset( $data [ 'author' ] ) ? $data [ 'author' ] : 100,
            'putway'    =>  isset( $data [ 'putway' ] ) ? $data [ 'putway' ] : 100,
            'charge'    =>  isset( $data [ 'charge' ] ) ? $data [ 'charge' ] : 100,
            'status'    =>  isset( $data [ 'status' ] ) ? $data [ 'status' ] : 100,
            'keywords'  =>  isset( $data [ 'keywords' ] ) ? $data [ 'keywords' ] : '',
        ];
        //获取发布数据
        //获取权限
        $accessIds = AccessAuthorization::getAccessibleIdsByUserId( cmf_get_current_admin_id() );
        $userList = Db::name( 'user' )->where( 'id' , 'IN' , $accessIds )->field( 'id,user_login' )->select()->toArray();
        $list = Db::name('module_store')->where( 'author_id' , 'IN' , $accessIds )->field('id,name,title,describe,author,price,version,status,step,putway');
        //搜索参数
        if( !empty( $search [ 'search' ] ) ){
            //模块标识
            if( $search [ 'module' ] != 100 ){
                $list = $list->where( 'name' , 'LIKE' , $search [ 'module' ]  );
            }
            //作者
            if( $search [ 'author' ] != 0 ){
                $list = $list->where( 'author_id' , '=' , $search [ 'author' ]  ) ;
            }
            //状态
            if( $search [ 'status' ] != 100 ){
                if( $search [ 'status' ] == 99 ){
                    $list = $list->where( 'status' , 'IN' , '(0,3)' );
                }else{
                    $list = $list->where( 'status' , '=' , $search [ 'status' ] );
                }
            }
            //付费
            if( $search [ 'charge' ] != 100 ){  
                if( $search [ 'charge' ] == 0 ){
                    //免费
                    $list = $list->where( 'price' , '=' , 0 );
                }else if( $search [ 'charge' ]  == 1 ){
                    //收费
                    $list = $list->where( 'price' , '>' , 0 );
                }
               
            }
            //上架
            if( $search [ 'putway' ] != 100 ){
                $list = $list->where( 'putway' , '=' , $search [ 'putway' ] );
            }

            //关键字
            if( $search [ 'keywords' ] != '' ){
                $kw = $search[ 'keywords' ];
                $list = $list->where( '`title`|`name`|`describe`' , 'LIKE' ,"%$kw%" );
            }

        }
        $list = $list ->order( 'status ASC' )->paginate( 30 );

		
		$listArr = json_decode( json_encode($list) , true );
		$currentPage = ($listArr['current_page']-1)*30;
		

        //获取所有模块
        $moduleList = Db::query( 'SELECT  DISTINCT `name` , `title` from `cmf_module_store` ' );
        $this->assign( 'search' , $search );
        //获取模块分类
        $category = ModuleCategoryController::getCategory();
        $this->assign( 'category' , $category );
		
		$this->assign( 'currentPage' , $currentPage);
        $this->assign( 'moduleList' , $moduleList );
        $this->assign( 'userList' , $userList );
        $this->assign( 'statusColor' , self::$statusColor );
        $this->assign( 'statusStr' , self::$statusStr );
        $this->assign( 'list' , $list );
    	return $this->fetch();
    }

    /**
     * 发布
     */
    public function add()
    {
    	return $this->fetch();
    }
	
	//回退操作
	/**
     *  删除模块
     *  @adminMenu(
     *     'name'   => '模块审核回退操作',
     *     'parent' => 'index',
     *     'display'=> false,
     *     'hasView'=> false,
     *     'order'  => 1000,
     *     'icon'   => '',
     *     'remark' => '模块审核回退操作',
     *     'param'  => ''
     * )
     */
	public function returnStep()
	{
		$param = $this->request->param();
		$res = Db::name( 'module_store' )->where( 'id' , $param['id'] )->update(['step'=>$param['step'] , 'status'=>$param['status']]);
		if( !$res ){
			return zy_json_echo(false , '回退操作失败，请稍候再试！');
		}
		
		return zy_json_echo(true,'操作成功！');
	}

    /**
     * 发布模块保存
     */
    public function addPost()
    {
    	$param = $this->request->param();
    	$data = $param['data'];
    	if( true !== ( $result = $this->validateData ( $data ) ) ){
    		return zy_json_echo(false,$result);
    	}
    	//验证器
    	dump($data);
    }

    /**
     *  删除模块
     *  @adminMenu(
     *     'name'   => '删除模块',
     *     'parent' => 'index',
     *     'display'=> false,
     *     'hasView'=> false,
     *     'order'  => 1000,
     *     'icon'   => '',
     *     'remark' => '删除模块',
     *     'param'  => ''
     * )
     */
    public function del()
    {
        if( !$this->request->isPost() ){
            return zy_json_echo( false , '请求类型错误，请检查！' );
        }
        $data = $this->request->param();
        $id = $data['id'];
        $res = Db::name( 'module_store' )->where( 'id' , $id )->delete();
        if( !$res ){
            //删除日志信息
            Db::name( 'module_audit_log' )->where( 'module_id' , $id )->delete();
            return zy_json_echo( false , '删除失败，请稍后再试！' );
        }
        return zy_json_echo( true, '删除成功！' );
    }

    /**
     * 数据验证
     */
    private function validateData( $data )
    {
    	$rule = [
		    'name'  => 'require',
		    'title'   => 'require',
		    'version' => 'require',
		];

		$msg = [
		    'name.require' => '模块中文名不能为空！',
		    'title.require'     => '模块标识不能为空！',
		    'version.require'   => '版本号不能为空！',
		    'describe'  => '简介不能为空！',
		    'introduce'        => '功能介绍不能为空！',
		];

		$validate = new Validate($rule, $msg);
		if( !$validate->check($data) ){
			return $validate->getError();
		}
		return true;
    }

    /**
     *检查菜单信息
     *1、检查待申请中的数据
     *2、检查菜单库中的数据
     */
    public function checkModuleMenu()
    {
        //模块标识都以大驼峰形式命名
        $data = $this->request->param();
        $moduleName = $data ['moduleName'];
        $moduleSymbol = $data ['moduleSymbol'] ;
        if( empty( trim( $moduleSymbol ) ) ){
            return zy_json_echo( false , '模块名不能为空。');
        }

        //禁用非法字符
        if( !preg_match('/^[A-Za-z]+$/i', $moduleSymbol) ){
            return zy_json_echo( false , '模块名只能是字母组合，不能存在数字或非法字符。');
        }

        $find = Db::name( 'module_store' )->where( 'name' , $moduleSymbol )->where( 'status' , '<>' , 4 )->find();
        if( !empty( $find ) ){
            return zy_json_echo( false , '模块已被申请，但还未被通过审核，无法发布新版本，请检查输入。');
        }

        $app = 'plugin/'.$moduleSymbol;
        $find1 = Db::name( 'admin_menu')->where( 'app' , $app ) ->where( [ 'controller'=>'AdminIndex' , 'action'=>'index'] ) ->find();
        if( !empty( $find1 ) ){
            if( $app !== $find1 ['app']   ){
                return zy_json_echo( false , '模块命名不规范，请检查输入。');
            }
            return zy_json_echo( true , '模块已存在,发布升级版本请修改版本号。',$find1['name'] );
        }
        return zy_json_echo( true , '模块名可用。' );
    }

    /**
     * 发布新模块
     * @adminMenu(
     *     'name'   => '发布模块',
     *     'parent' => 'index',
     *     'display'=> true,
     *     'hasView'=> true,
     *     'order'  => 1000,
     *     'icon'   => '',
     *     'remark' => '发布模块',
     *     'param'  => ''
     * )
     */
    public function publish()
    {
        $data = $this->request->param();
        //获取模块分类
        $category = ModuleCategoryController::getCategory();
        $this->assign( 'category' , $category );

        if( isset( $data['id'] ) && !empty( $data ['id'] ) ){
            //读取已有模块
            $module = Db::name( 'module_store' )->where( 'id' , $data ['id'] )->find();
            $previewList = [];
            if( !empty($module['preview']) ){
                $previewList = explode(',', $module['preview']);
            }
            if( $module['step'] <= 1 && $module['status'] == 0 ){
                //第一步 未提交
                //跳转第一步编辑
                $this->assign( 'module' , $module );
            }else if( $module['step'] == 2 && $module['status'] == 3  ){
                // 第二步未完成时
                //  跳转到第二步编辑页面
                $this->assign( 'module' , $module );  
                $this->assign( 'previewList' , $previewList );
                return $this->fetch( 'step_two' );
            }else if( $module['step'] == 2 && $module['status'] == 4 ){
                //第二部 通过时 
                //跳转到 全部详情页面
				if(cmf_get_current_admin_id() == 1 ){
					$this->assign( 'module' , $module );  
					$this->assign( 'previewList' , $previewList );
					return $this->fetch( 'step_two' );
				}
                return $this->particular( $data ['id'] );
            }else{
                //跳转审核页面
                return $this->auditResult( $data ['id'] );
            }
        }
        return $this->fetch('step_one');
    }

    /**
     * 步骤1提交数据
     */
    public function stepOnePost()
    {
        $data = $this->request->param();
        $id = $data ['id'];
        $type = $data ['type'];
        $data = $data['data'];

        //检查版本号
        $version = $data ['version'];
        $res = $this->checkVersion( $id , $version );
        if( false == $res ){
            return zy_json_echo(false, '版本号错误，请检查！');
        }
        $data ['version'] = $res;
        
        if( $type == 'save' ){
        
            if( $id != 0 ){
                //更新数据
                Db::name('module_store')->where('id',$id)->update($data);
            }else{
                //获取开发者信息 //保存数据
                $data ['author_id'] = cmf_get_current_admin_id();
                $data ['author'] = Db::name( 'user' )->where( 'id' , $data['author_id'] )->value('user_login'); 
                $data ['add_time'] = time();
                $id = Db::name('module_store')->insertGetId($data);
            }
            
            if( !$id ){
                return zy_json_echo(false , '数据保存失败，请稍后再试！');
            }
            //数据保存成功，-返回id
            return zy_json_echo(true , '数据保存成功！' , ['res'=>'id', 'id'=> $id] );
        }else if( $id !=0 && $type == 'audit' ){
            //更新一次数据  步骤改为1 状态改为 1 审核中
            $data [ 'step' ] = 1 ;
            $data [ 'status'] = 1;
            //提交审核 修改状态
            $res = Db::name( 'module_store' )->where( 'id' , $id )->update( $data );
            if( !$res ){
                return zy_json_echo(false,'审核提交失败，请稍后再试！');
            }
            $insert['content'] = '<span style="color:blue;" class="glyphicon glyphicon-refresh"></span>提交审核成功，请等待！';
            $insert['module_id'] = $id;
            $this->addLog( $insert );
            //提交成功，跳转到审核结果页面
            $url = cmf_plugin_url('Appmarket://publish/auditResult')."?id=$id";
            return zy_json_echo(true,'审核信息提交成功！',[ 'res'=> 'url' , 'url'=> $url ]);
        }

    }

    /**
     * 步骤二提交
     */
    public function stepTwoPost()
    {
        $data = $this->request->param();
        $id = $data ['id'];
        $type = $data ['type'];
        $data = $data['data'];

        if( $type == 'save' ){
            //保存
            $res = Db::name( 'module_store' )->where( 'id' , $id )->update( $data );
            if( !$res ){
                return zy_json_echo(false , '数据保存失败，请稍后再试！');
            }
            //数据保存成功
            return zy_json_echo(true , '数据保存成功！' );
        }else if( $type == 'audit' ){
            //提交审核
            $data ['step'] = 2 ;
            $data['status'] = 1 ;
            $res = Db::name( 'module_store' )->where( 'id' , $id )->update( $data );
            if( !$res ){
                $url = '{:cmf_plugin_url("Appmarket://publish/publish")}';
                return zy_json_echo(false,'审核提交失败，请稍后再试！',['res'=>'url','url'=>$url]);
            }
            $insert['content'] = '<span style="color:blue;" class="glyphicon glyphicon-refresh"></span>提交审核成功，请等待！';
            $insert['module_id'] = $id;
            self::addLog( $insert );
            //提交成功，跳转到审核结果页面
            $url = cmf_plugin_url('Appmarket://publish/auditResult')."?id=$id";
            return zy_json_echo(true,'审核信息提交成功！',[ 'res'=> 'url' , 'url'=> $url ]);
        }
    }

    /**
     *版本号检测
     *返回 正确： string version  错误 ： false  
     */
    private function checkVersion(  $id , $version )
    {
		$versionArr = explode( '.' , $version );
		$tem = '';
		foreach( $versionArr as $key => $value ){
			$tem .= intval( $value , 0 );
		}
        //如果id不存在，说明是新增，新增的数据默认版本号就是1.0
        if( empty($id) ) return $version;

        //如果存在，检测版本号是否合法
        $find = Db::name( 'module_store' )->where( 'id' , $id )->find();
        //如果未找到模块 返回false
        
		//待优化部分：查询模块的最高版本，修改版本的时候是以最高版本（去除当前版本）为基准进行检查 不得小于最高版本，
        if( empty( $find ) )  return false;
		

        $oldVersion = intval( str_replace( '.', '' , $find['version'] ) , 0 );
        $newVersion = intval( str_replace( '.', '' , $tem ) , 0 );
        if( $oldVersion == 0 || $newVersion == 0 || $newVersion < $oldVersion ){
            return false;
        }
        return $version;
    }

    /**
     * 审核结果页面
     * @adminMenu(
     *     'name'   => '审核结果查看',
     *     'parent' => 'index',
     *     'display'=> false,
     *     'hasView'=> true,
     *     'order'  => 1000,
     *     'icon'   => '',
     *     'remark' => '审核结果查看',
     *     'param'  => ''
     * )
     */
    public function  auditResult( $id )
    {   
        //读取审核结果
        $log = Db::name( 'module_audit_log' )->where( 'module_id' , $id )->order('add_time desc')->select()->toArray();
        $log = autoHtmlspecialcharsDecode($log);
        $module = Db::name( 'module_store' )->where( 'id' , $id )->find();
        $statusMessage = '';
        switch ( $module ['status'] ) {
            case 1:
                $statusMessage = '正在审核中，请稍后...';
                break;
            case 2:
                $statusMessage = '审核失败，请稍后...';
                break;
            default:
                if( $module ['step'] == 1 ){
                    $statusMessage = '当前处于流程一';
                }else if( $module ['step'] == 2 ){
                    $statusMessage = '当前处于流程二';
                }
                break;
        }
        $this->assign( 'module' , $module );
        $this->assign( 'id' , $id );
        $this->assign('status' , $module['status'] );
        $this->assign('statusMessage' ,  $statusMessage  );
        $this->assign( 'logList' , $log );
        return $this->fetch('/publish/audit_result');
    }

    /**
     * 获取模块信息
     * 
     */
    private function getModuleInfo( $id )
    {
        if( empty($id) ){
            return zy_json_echo( false, '未找到相应模块！');
        }
        return Db::name( 'module_store' )->where( 'id' , $id )->find();
    }

    /**
     * 上传思维导图文件
     */
    public function mindMap( $id )
    {
        $module = $this->getModuleInfo( $id );
        $path = cmf_parse_name( $module[ 'name' ] ).DS.$module['version'].DS.'mindMap';
        return $this->uploadFile ( $path , 10 , ['xmind','zip','rar'] );   
    }

    /**
     * 上传流程图文件
     */
    public function flowChart( $id )
    {
        $module = $this->getModuleInfo( $id );
        $path = cmf_parse_name( $module[ 'name' ] ).DS.$module['version'].DS.'flowChart';
        return $this->uploadFile ( $path , 10 , ['rp','zip','rar'] );
    }

    /**
     * 上传ui图文件
     */
    public function uiMap( $id )
    {
        $module = $this->getModuleInfo( $id );
        $path = cmf_parse_name( $module[ 'name' ] ).DS.$module['version'].DS.'uiMap';
        return $this->uploadFile ( $path , 10 , ['rp','zip','rar'] );
    }

    /**
     * 上传预览图
     */
    public function preview( $id )
    {
        $module = $this->getModuleInfo( $id );
        $path = cmf_parse_name( $module[ 'name' ] ).DS.$module['version'].DS.'preview';

        $timeMd5=md5(time());
        //产生随机数避免名字重复
        $start = rand(5,20);
        $length = rand(5,10);
        $fileName = substr( $timeMd5 , $start , $length );

        return $this->uploadFile ( $path , 10 , ['jpg','bmp','png','gif','jpeg'] , $fileName );
    }

    /**
     * 上传模块压缩文件
     */
    public function upResource($id)
    {
        $module = $this->getModuleInfo( $id );
        $path = cmf_parse_name( $module[ 'name' ] ).DS.$module['version'].DS.'resource';
        return $this->uploadFile ( $path , 100 , ['zip'] );
    }

    /**
     * 删除预览图
     */
    public function trashFile()
    {
        $data = $this->request->param();
        $file = $data['file'];
        $id = $data['id'];
        $preview = $data['preview'];
        if( !empty( $id ) ){
            //更新数据库数据
            Db::name( 'module_store' )->where( 'id' , $id )->update( [ 'preview' => $preview ]);
        }
        $path = APP_PATH.'..'.DS.'public'.DS.$file;
        if( file_exists( $path ) ){
            unlink( $path );
        }                
    }

    /**
     * 上传文件公共方法
     */
    private function uploadFile ( $path = '' , $size = 10 , $exts = ['zip'] , $fileName = '' )
    {
        try {
            $upload = new Upload();
            $upload->setSize( $size );
            if( !empty( $exts ) ){
                $upload->exts = $exts;
            }
            if( !empty( $fileName ) ){
                $upload->fileName = $fileName;
            }
            $upload->rootPath = $this->rootPath.DS.$path;
            $upload->setResourceInfo( $_FILES );
            return $upload->uploadFile();
        } catch (\Exception $e) {
            return zy_json_echo( false , $e->getMessage() );
        }
    }

    /**
     * 审核日志填写
     */
    public static function addLog( $insert )
    {
        $insert ['add_time'] = time();
        $insert ['issue_id'] = cmf_get_current_admin_id();
        $insert ['issue'] = Db::name( 'user' )->where( 'id' , $insert ['issue_id'] )->value('user_login');
        try {
            Db::name('module_audit_log')->insertGetId( $insert );
        } catch (\Exception $e) {
            throw new \Exception( '写入审核日志异常！' );
        }       
    }

    /**
     *重新提交数据
     */
    public function reSubmit()
    {
        $data  = $this->request->param();
        $id = $data ['id'];
        $status = $data ['status'];
        if( $id != 0  && $status == 2 ){
            $find = Db::name( 'module_store' )->where( 'id' , $id )->find();
            $status = ( $find['step'] == 1 ) ? 0 : 3 ; 
            //跳转到发布页面
            $url = cmf_plugin_url('Appmarket://publish/publish')."?id=$id";
            Db::name( 'module_store' )->where( 'id' , $id )->update( [ 'status' => $status ] );
            return zy_json_echo (true , '页面跳转中，请稍等！', $url);
        }else{
            return zy_json_echo(false,'操作错误！');
        }
    }

    /**
     * 模块详情页面
	 *@adminMenu(
     *     'name'   => '模块详情',
     *     'parent' => 'index',
     *     'display'=> false,
     *     'hasView'=> true,
     *     'order'  => 1000,
     *     'icon'   => '',
     *     'remark' => '模块详情',
     *     'param'  => ''
     * )
     */
    public function particular( $id )
    {
        $module = Db::name( 'module_store' )->where( 'id' , $id )->find();
		$module['category_name'] = Db::name('module_category')->where('id',$module['category' ])->value('name');
        $previewList = [];
        if( !empty($module['preview']) ){
            $previewList = explode(',', $module['preview']);
        }
        //获取狭隘主机地址
        $address = ConfigController::getDownloadHostAddress();
        $this->assign( 'address' , $address );
        $this->assign( 'module' , $module );
        $this->assign( 'previewList' , $previewList );
        return $this->fetch( 'publish/particular' );
    }


    /**
     *应用上下架操作
     *@adminMenu(
     *     'name'   => '上架/下架',
     *     'parent' => 'index',
     *     'display'=> false,
     *     'hasView'=> false,
     *     'order'  => 1000,
     *     'icon'   => '',
     *     'remark' => '上架/下架',
     *     'param'  => ''
     * )
     */
    public function putway( $id , $num )
    {   
        try {
            $res = Db::name('module_store')->where( 'id' , $id )->update( [ 'putway' => $num ] );
            if( !$res ){
                return zy_json_echo( false, '操作失败，请稍后再试！' );
            }
            return zy_json_echo( true, '操作成功！');
        } catch (\Exception $e) {
            return zy_json_echo(false,'异常：'.$e->getMessage());
        }
    }

}